https://www.bilibili.com/video/BV15b4y1a7yG/:Spring Boot2https://www.bilibili.com/video/BV1Es4y1q7Bf/:Spring Boot3https://www.bilibili.com/video/BV19K4y1L7M:Spring Boot2(p32 - p42 讲解 Spring MVC 源码和内容协商源码)StarterautoconfigureMETA-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件xxxAutoConfigurationxxxProperties@Contional 派生的条件注解进行判断 是否组件生效自动装配通过 @SpringBootApplication 注解来执行,该注解主要功能:
@Component 等注解修饰的类添加到容器中@SpringBootConfiguration 就是 @Configuration,容器中的组件,配置类。spring IOC 启动就会加载创建这个类对象。
@SpringBootConfiguration 注解里引用了 @EnableAutoConfiguration、@ComponentScan 注解
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {}@EnableAutoConfiguration 开启自动配置,该注解引用了 @AutoConfigurationPackage 注解。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}@AutoConfigurationPackage:扫描主程序包:加载自己的组件
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
}该注解利用 @Import(AutoConfigurationPackages.Registrar.class) 想要给容器中导入组件
把主程序所在的 包 的所有组件导入进来
为什么 SpringBoot 默认只扫描主程序所在的包及其子包,就是这个注解 AutoConfigurationPackage 实现的
除此之外 @EnableAutoConfiguration 使用 @Import(AutoConfigurationImportSelector.class) 注解,该注解加载所有自动配置类,即 Spring Boot 加载内置的 Starter。
@ComponentScan:组件扫描:排除一些组件(哪些不要)、排除前面已经扫描进来的配置类、和自动配置类。
创建自定义 Starter 项目,引入 spring-boot-starter 基础依赖
编写模块功能,引入模块所有需要的依赖
编写 xxProperties 属性类,可以读取 application.yml 的配置
@ConfigurationProperties(prefix = "user") // 此属性类和配置文件指定前缀绑定
@Data
public class UserProperties {
private String name;
private String age;
private String email;
}写 xxxAutoConfiguration 自动配置类,导入该项目需要的组件,包括上面的 xxProperties 组件
引入 spring-boot-configuration-processor 依赖,该依赖帮助写 application.yml 时有语法提示
写完一个 Started 后,我们希望其他项目只需要引入 Started 依赖就可以使用里面的组件,但是遇到一个问题:
为什么这些组件默认不会扫描进去?
因为 Starter 所在的包和引入它的项目的主程序所在的包不是父子层级,因此不能自动扫描到容器。
因此我们有两个方式可以将写的内容导入到项目的容器:
Started 提供 @EnableXxx 注解,开发者在主程序使用 @EnableXxx 即可导入 Stated 组件,该注解内部其实使用 @Import(xxx.class) 将 Started 的组件导入到容器
按照 SpringBoot 的 SPI 机制,将需要导入的组件写到 resource/META-INF 下的 spring.factory(Spring Boot 2.X) 或者 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(Spring Boot 3.X)里,Spring Boot 会自动扫描该文件
视频:https://www.bilibili.com/video/BV15b4y1a7yG?p=137。